import { useRef, useEffect, useCallback } from "react";

function useDebounce<T>(cb: (value?: any) => Promise<T | undefined>) {
  const flagRef = useRef(false);
  const cbRef = useRef(cb);
  const timer = useRef<NodeJS.Timeout>();

  useEffect(() => {
    cbRef.current = cb;
  }, [cb]);

  const doWork = useCallback(
    async (value?: any) => {
      if (flagRef.current) {
        return;
      }
      flagRef.current = true;
      let data: T | undefined = undefined;
      try {
        data = await cbRef.current(value);
        flagRef.current = false;
      } catch (e) {
        flagRef.current = false;
        throw e;
      }
      return data;
    },
    [cb]
  );

  useEffect(() => {
    return () => {
      timer.current && clearTimeout(timer.current);
      flagRef.current = false;
    };
  }, []);
  return doWork;
}

export default useDebounce;
